/**
 * IPC 通信工具模块
 * 提供渲染进程与主进程通信的方法
 */

// 通过预加载脚本访问 ipcRenderer
const ipcRenderer = (window as any).electron?.ipcRenderer

/**
 * 标准响应格式
 */
export interface StandardResponse<T = any> {
  code: number        // 状态码：200=成功，400=客户端错误，500=服务器错误
  data?: T           // 响应数据
  message: string    // 响应消息
  timestamp: number  // 时间戳
}

/**
 * 状态码常量
 */
export const ResponseCode = {
  SUCCESS: 200,           // 成功
  CREATED: 201,           // 创建成功
  BAD_REQUEST: 400,       // 请求错误
  NOT_FOUND: 404,         // 资源不存在
  CONFLICT: 409,          // 冲突（如重复创建）
  INTERNAL_ERROR: 500,    // 内部错误
  DATABASE_ERROR: 501,    // 数据库错误
  VALIDATION_ERROR: 502,  // 验证错误
  FILE_ERROR: 503         // 文件操作错误
} as const

/**
 * IPC错误类
 */
export class IPCError extends Error {
  constructor(
    message: string,
    public code: number,
    public data?: any
  ) {
    super(message)
    this.name = 'IPCError'
  }
}

/**
 * 发送消息到主进程（无需回复）
 * @param channel 通道名称
 * @param args 参数列表
 */
export function send(channel: string, ...args: any[]): void {
  ipcRenderer.send(channel, ...args)
}

/**
 * 调用主进程方法并等待结果
 * @param channel 通道名称
 * @param args 参数列表
 * @returns 主进程返回的结果
 */
export async function invoke<T = any>(channel: string, ...args: any[]): Promise<T> {
  return await ipcRenderer.invoke(channel, ...args)
}

/**
 * 调用主进程方法并处理标准响应格式
 * @param channel 通道名称
 * @param args 参数列表
 * @returns 解析后的数据
 * @throws IPCError 当操作失败时抛出错误
 */
export async function invokeStandard<T = any>(channel: string, ...args: any[]): Promise<T> {
  const response: StandardResponse<T> = await ipcRenderer.invoke(channel, ...args)

  if (response.code === ResponseCode.SUCCESS || response.code === ResponseCode.CREATED) {
    return response.data as T
  } else {
    throw new IPCError(response.message, response.code, response.data)
  }
}

/**
 * 安全调用主进程方法，返回结果对象而不抛出异常
 * @param channel 通道名称
 * @param args 参数列表
 * @returns 包含成功状态和数据的结果对象
 */
export async function invokeSafe<T = any>(channel: string, ...args: any[]): Promise<{
  success: boolean
  data?: T
  error?: { message: string; code: number; data?: any }
}> {
  try {
    const response: StandardResponse<T> = await ipcRenderer.invoke(channel, ...args)

    if (response.code === ResponseCode.SUCCESS || response.code === ResponseCode.CREATED) {
      return {
        success: true,
        data: response.data
      }
    } else {
      return {
        success: false,
        error: {
          message: response.message,
          code: response.code,
          data: response.data
        }
      }
    }
  } catch (error) {
    return {
      success: false,
      error: {
        message: error instanceof Error ? error.message : '未知错误',
        code: ResponseCode.INTERNAL_ERROR,
        data: error
      }
    }
  }
}

/**
 * 注册监听主进程发送的消息
 * @param channel 通道名称
 * @param listener 监听回调函数
 * @returns 用于取消监听的函数
 */
export function on<T = any>(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: T[]) => void): () => void {
  ipcRenderer.on(channel, listener)
  return () => {
    ipcRenderer.removeListener(channel, listener)
  }
}

/**
 * 注册一次性监听主进程发送的消息
 * @param channel 通道名称
 * @param listener 监听回调函数
 */
export function once<T = any>(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: T[]) => void): void {
  ipcRenderer.once(channel, listener)
}

/**
 * 取消监听主进程消息
 * @param channel 通道名称
 * @param listener 监听回调函数
 */
export function off(channel: string, listener: (...args: any[]) => void): void {
  ipcRenderer.removeListener(channel, listener)
}

/**
 * 取消所有监听
 * @param channel 通道名称，如果不提供则取消所有通道的监听
 */
export function removeAllListeners(channel?: string): void {
  if (channel) {
    ipcRenderer.removeAllListeners(channel)
  } else {
    ipcRenderer.removeAllListeners()
  }
}

/**
 * 测试 IPC 连接
 * @returns 是否成功
 */
export async function testConnection(): Promise<boolean> {
  try {
    send('ping')
    return true
  } catch (error) {
    console.error('IPC 连接测试失败:', error)
    return false
  }
}

/**
 * 获取应用版本
 * @returns 应用版本号
 */
export async function getAppVersion(): Promise<string> {
  return await invoke<string>('get-app-version')
}

/**
 * 获取应用信息
 * @returns 应用信息对象
 */
export async function getAppInfo(): Promise<{
  version: string
  name: string
  appPath: string
  locale: string
  isPackaged: boolean
  platform: string
  arch: string
  osVersion: string
  osName: string
}> {
  return await invoke('get-app-info')
}

/**
 * 通知启动界面已准备就绪
 */
export function notifySplashReady(): void {
  send('splash-ready')
}

/**
 * 监听应用准备就绪事件
 * @param callback 回调函数
 * @returns 取消监听的函数
 */
export function onAppReady(callback: () => void): () => void {
  const listener = () => callback()
  ipcRenderer.on('app-ready', listener)
  return () => {
    ipcRenderer.removeListener('app-ready', listener)
  }
}

/**
 * 通知启动界面已完成
 */
export function notifySplashComplete(): void {
  send('splash-complete')
}

// ==================== 项目相关API ====================

/**
 * 项目数据接口
 */
export interface ProjectData {
  id?: string
  name: string
  description?: string
  resolution?: { width: number; height: number }
  frameRate?: number
  duration?: number
  thumbnail?: string
  filePath?: string
  metadata?: any
}

/**
 * 创建新项目
 * @param projectData 项目数据
 * @returns 创建的项目
 */
export async function createProject(projectData: {
  name: string
  description?: string
  resolution?: { width: number; height: number }
  frameRate?: number
}): Promise<ProjectData> {
  return await invokeStandard<ProjectData>('project:create', projectData)
}

/**
 * 获取所有项目
 * @returns 项目列表
 */
export async function getAllProjects(): Promise<ProjectData[]> {
  return await invokeStandard<ProjectData[]>('project:getAll')
}

/**
 * 打开项目
 * @param id 项目ID
 * @returns 项目数据
 */
export async function openProject(id: string): Promise<ProjectData> {
  return await invokeStandard<ProjectData>('project:open', { id })
}

/**
 * 保存项目
 * @param id 项目ID
 * @param data 要更新的数据
 * @returns 是否成功
 */
export async function saveProject(id: string, data: Partial<ProjectData>): Promise<boolean> {
  return await invokeStandard<boolean>('project:save', { id, data })
}

/**
 * 删除项目
 * @param id 项目ID
 * @returns 是否成功
 */
export async function deleteProject(id: string): Promise<boolean> {
  return await invokeStandard<boolean>('project:delete', { id })
}

/**
 * 导出项目
 * @param id 项目ID
 * @param format 导出格式
 * @param options 导出选项
 * @returns 导出文件路径
 */
export async function exportProject(
  id: string,
  format: 'mp4' | 'gif' | 'webm',
  options: {
    quality?: number
    fps?: number
    resolution?: { width: number; height: number }
    startFrame?: number
    endFrame?: number
  } = {}
): Promise<{ path: string }> {
  return await invokeStandard<{ path: string }>('project:export', { id, format, options })
}

// ==================== 安全版本API（不抛出异常）====================

/**
 * 安全创建项目
 */
export async function createProjectSafe(projectData: {
  name: string
  description?: string
  resolution?: { width: number; height: number }
  frameRate?: number
}) {
  return await invokeSafe<ProjectData>('project:create', projectData)
}

/**
 * 安全获取所有项目
 */
export async function getAllProjectsSafe() {
  return await invokeSafe<ProjectData[]>('project:getAll')
}

/**
 * 安全保存项目
 */
export async function saveProjectSafe(id: string, data: Partial<ProjectData>) {
  return await invokeSafe<boolean>('project:save', { id, data })
}

/**
 * 安全删除项目
 */
export async function deleteProjectSafe(id: string) {
  return await invokeSafe<boolean>('project:delete', { id })
}

/**
 * 安全导出项目
 */
export async function exportProjectSafe(
  id: string,
  format: 'mp4' | 'gif' | 'webm',
  options: {
    quality?: number
    fps?: number
    resolution?: { width: number; height: number }
    startFrame?: number
    endFrame?: number
  } = {}
) {
  return await invokeSafe<{ path: string }>('project:export', { id, format, options })
}